﻿#include "EditorDebugAndRunAbilityGroupView.h"

#include "EditorDebugAndRunAbilityGroupViewModel.h"

#include "Widgets/Widget.h"
#include "Widgets/EditorImageButton.h"
#include "Widgets/RectangleWidget.h"

#include "Widgets/Positioners/HorizontalPositionerWidget.h"
#include "Widgets/Window.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/ImageWidget.h"
#include "Widgets/EditorComboBoxWidget.h"
#include "Widgets/EditableTextWidget.h"

void REditorDebugAndRunAbilityGroupView::BindViewModel(TSharedObjectPtr<REditorAbilityViewModel> InViewModel)
{
    Super::BindViewModel(InViewModel);

    DebugAndRunViewModel=InViewModel;



}

void REditorDebugAndRunAbilityGroupView::FillOperations(TSharedObjectPtr<RWidget> InTitleBar)
{
    const float RunButtonWidth=24;
    const float ConfigurationSelectorWidth=80;
    const float PortWidth=35;

    const float Padding=5;

    //add compile operation
    auto CompileButton=WHE::CreateImageButton(
        DebugAndRunViewModel->CompileIcon
        ,CString(U"编译")
        ,[this](){
            DebugAndRunViewModel->Compile();
        }
        ,InTitleBar
        ,RunButtonWidth
    );

    CompileButton->Anchor.VerticalCenterReference=InTitleBar;

    //add Run operation
    auto RunButton=WHE::CreateImageButton(
        DebugAndRunViewModel->StartDebugIcon
        ,CString(U"开始调试")
        ,[this](){
            DebugAndRunViewModel->StartDebug();
        }
        ,InTitleBar
        ,RunButtonWidth
    );

    CompileButton->Anchor.RightReference=RunButton;
    CompileButton->Anchor.RightReferenceEdge=EHorizontalWidgetEdge::Left;
    CompileButton->Anchor.RightOffset=Padding;

    RunButton->Anchor.VerticalCenterReference=InTitleBar;

    auto ConfigurationSelector=NewWidget<REditorComboBoxWidget>(InTitleBar);
    ConfigurationSelector->Anchor.VerticalCenterReference=InTitleBar;
    ConfigurationSelector->Height=20;
    ConfigurationSelector->Width=ConfigurationSelectorWidth;
    ConfigurationSelector->SelectedItem=[this](){
        return DebugAndRunViewModel->GetCurrentConfigurationName();
    };
    ConfigurationSelector->Items=[this](){
        return DebugAndRunViewModel->GetConfigurationNames();
    };
    ConfigurationSelector->OnSelectionChanged.Bind([this](const CString& NewItem){
        DebugAndRunViewModel->SetCurrentConfigurationName(NewItem);
    });

    RunButton->Anchor.RightReference=ConfigurationSelector;
    RunButton->Anchor.RightReferenceEdge=EHorizontalWidgetEdge::Left;
    RunButton->Anchor.RightOffset=Padding;

    auto Port=NewWidget<REditableTextWidget>(InTitleBar);
    Port->Anchor.VerticalCenterReference=InTitleBar;
    Port->Height=20;
    Port->Width=PortWidth;
    Port->Text=[this](){
        return CString(DebugAndRunViewModel->GetPort());
    };
    Port->OnEditStopped.BindLambda([this](ETextEditStopReason Reason,const CString& NewText){
        if(Reason==ETextEditStopReason::Cancel)
        {
            return;
        }
        DebugAndRunViewModel->SetPort(NewText.ToUInt64());
    });

    
    ConfigurationSelector->Anchor.RightReference=Port;
    ConfigurationSelector->Anchor.RightReferenceEdge=EHorizontalWidgetEdge::Left;
    ConfigurationSelector->Anchor.RightOffset=Padding;


    Port->Anchor.RightReference=InTitleBar;
    Port->Anchor.RightOffset=30;

    //add more operations
    Super::FillOperations(InTitleBar);

    //TODO find a better palce to create debug bar
    //create debug bar
    CreateDebugBar(InTitleBar->GetWindow());
}

void REditorDebugAndRunAbilityGroupView::CreateDebugBar(TSharedObjectPtr<RWindow> InWindow)
{
    auto DebugBar=NewWidget<RRectangleWidget>(InWindow->GetRootWidget());
    DebugBar->Width=DebugAndRunViewModel->DebugBarWidth;
    DebugBar->Height=DebugAndRunViewModel->DebugBarHeight;
    DebugBar->FillColor=DebugAndRunViewModel->DebugBarColor;
    DebugBar->BorderColor=DebugAndRunViewModel->DebugBarBorderColor;
    DebugBar->BorderSize=2;
    DebugBar->Radius=DebugAndRunViewModel->DebugBarRadius;
    DebugBar->Visible=[this](){
        return DebugAndRunViewModel->GetDebuggingBarVisible();
    };
    DebugBar->X=DebugAndRunViewModel->GetDebugBarInitialX(InWindow);
    DebugBar->Y=DebugAndRunViewModel->GetDebugBarInitialY();

    auto DragMouse=NewWidget<RMouseWidget>(DebugBar);
    DragMouse->Anchor.Fill(DebugBar);
    DragMouse->Drag->bIsEnabled=true;
    DragMouse->Drag->Target=DebugBar;
    DragMouse->Drag->Direction=EDragDirection::Both;
    DragMouse->Drag->TargetWidgetMinX=0;
    RWindowWeakPtr WeakWindow=InWindow;
    DragMouse->Drag->TargetWidgetMaxX=
        [WeakWindow,this](){
            return this->DebugAndRunViewModel->GetDebugBarMaxX(WeakWindow);
        };
    DragMouse->Drag->TargetWidgetMinY=0;
    DragMouse->Drag->TargetWidgetMaxY= DebugAndRunViewModel->MaxDebugBarY;

    auto Layout=NewWidget<RHorizontalPositionerWidget>(DebugBar);
    Layout->Anchor.TopReference=DebugBar;
    Layout->Anchor.BottomReference=DebugBar;
    Layout->Anchor.LeftReference=DebugBar;
    Layout->Anchor.RightReference=DebugBar;
    Layout->Anchor.LeftOffset=DebugAndRunViewModel->DebugBarLeftPadding;
    Layout->Anchor.RightOffset=DebugAndRunViewModel->DebugBarRightPadding;

    auto Grip= NewWidget<RImageWidget>(Layout);
    Grip->Image=DebugAndRunViewModel->GripIcon;
    Grip->Width=DebugAndRunViewModel->DebugBarGripSize;
    Grip->Height=DebugAndRunViewModel->DebugBarGripSize;
    Grip->Anchor.VerticalCenterReference=Layout;

    auto ContinueButton=WHE::CreateImageButton(
        std::function<TSharedObjectPtr<RTexture2D>()>(   
        [this]()->TSharedObjectPtr<RTexture2D>
        {
            return DebugAndRunViewModel->GetContinuePauseIcon();
        })
        ,std::function<CString()>(   
        [this]()->CString
        {
            return DebugAndRunViewModel->GetContinuePauseToolTip();
        })
        ,[this](){
            DebugAndRunViewModel->OnContinuePauseClicked();
        }
        ,Layout
    );

    auto StopButton=WHE::CreateImageButton(
        DebugAndRunViewModel->StopIcon
        ,CString(U"停止")
        ,[this](){
            DebugAndRunViewModel->StopDebug();
        }
        ,Layout
    );

}
